var config = require('../data/config');
var launcher = require('./launcher');
/**
 * 全局的事件分发器
 * */

/**
 * {
 * 		'up.key':{
 * 			'grid': function
 * 		}
  * }
 */
var pool = {};
var poolOwner = {};
var _lock = null;

exports.trigger = function(event, params, exclude){
	var ret = 0;
	var arr = [];
	//普通事件
	var target = pool[event];
	arr.push(target);

	//属主事件
	var owner = event.substring(event.lastIndexOf('.')+1);
	target = poolOwner[owner];
	arr.push(target);

	var lock;
	if(_lock && _lock.owner == owner){
		lock = _lock.key;
	}

	var send = false;
	for(var i=0;i<2;i++){
		target = arr[i];
		if(!target){
			continue;
		}
		//后加入的事件, 有更高优先级
		//类似dialog浮层, 自然优先得到事件
		for(var j=target.length-1;j>=0;j--){
			var _target = target[j];
			//锁定转发状态, 检查key是否相符
			if(lock && lock != _target.key){
				continue;
			}
			if(!_target.obj){
				continue;
			}
			//传递exclude时, 排除这个分发对象
			if(exclude && _target.obj == exclude){
				continue;
			}
			//调试时
			if(config.debug){
				ret = _target.obj.onEvent(event, params);  //形式  function(e, param)
			}else{
				try{
					ret = _target.obj.onEvent(event, params);  //形式  function(e, param)
				}catch (e){
					console.log(e);
				}
			}
			if(_target.once){
				target.splice(j, 1);
			}
			//notice: 一个事件, 一旦有一个target接受了, 其他监听这个事件的lazy模块就不会触发加载
			//需要取消lazy, 或者换一个事件名
			if(ret){
				send = true;
			}
			if(ret == exports.result.stop){
				console.log(event + ' stopped by '+target[j].key);
				break;
			}else if(ret == exports.result.stopAll){
				console.log(event + ' stopped all by '+target[j].key);
				return;
			}
		}
	}

	if(!send){
		launcher.check(event, owner, params);
	}
};

exports.bind = function(event, key, obj){
	if(!pool[event]){
		pool[event] = [];
	}
	pool[event].push({
		key: key,
		obj: obj
	});
};

/**
 * 执行一次后就自动解绑
 * 注意使用场合
 * @param event
 * @param key
 * @param obj
 */
exports.bindOnce = function (event, key, obj) {
	if(!pool[event]){
		pool[event] = [];
	}
	exports.unbind(event, key);
	pool[event].push({
		key: key,
		obj: obj,
		once : true
	});
};

exports.unbind = function(event, key){
	if(!pool[event]){
		return;
	}
	var arr = pool[event];
	for(var i=0;i<arr.length;i++){
		if(arr[i].key == key){
			arr.splice(i, 1);
			break;
		}
	}
};

exports.unbindByKey = function(key) {
	for(var e in pool){
		if(!pool.hasOwnProperty(e)){
			continue;
		}
		exports.unbind(e, key);
	}
};

exports.bindOwner = function(owner, key, obj){
	if(!poolOwner[owner]){
		poolOwner[owner] = [];
	}
	poolOwner[owner].push({
		key: key,
		obj: obj
	});
};

exports.unbindOwner = function(owner, key){
	if(!poolOwner[owner]){
		return;
	}
	var arr = poolOwner[owner];
	for(var i=0;i<arr.length;i++){
		if(arr[i].key == key){
			arr.splice(i, 1);
			break;
		}
	}
};

/**
 * 封锁某一个类型的事件, 除了target为指定类型
 * @param owner
 * @param key
 */
exports.lock = function(owner, key) {
	_lock = {
		owner: owner,
		key: key
	};
};

exports.unlock = function() {
	_lock = null;
};

/**
 * 监听函数的返回值
 */
exports.result = {
	stop:-1,  //阻止在同层继续传播
	stopAll:-10   //阻止所有后续接受函数的传递
};

/**
 * 事件采用逆序
 * 事件前缀是动作
 * add: 对象有增加
 * del：对象有删除
 * change：对象有属性变化
 * show：对象展示
 * hide：对象隐藏
 * load：对象从外部加载
 * unload：对象即将销毁
 * err: 表示有错误发生
 */
exports.events = {
	global:{
		blur:'blur.global',
		undo:'undo.global',
		redo:'redo.global',
		drop:'drop.global',
		copy:'copy.global',
        flipH:'flipH.global',
        mirrorH: 'mirrorH.global',
		paste:'paste.global',
		scroll:'scroll.global',//由window转发空格事件
		dialog:'dialog.global'  //dialog获得确认, 继续执行
	},
	file:{
		load:'load.file',
		unload:'unload.file',
		save:'save.file',
		saveas:'saveas.file',
		exports:'export.file',
        exportMcz:"exportMcz.file",
		mc2bms:"mc2bms.file",
		imports:'import.file',
        importAnalyser:'import.analyser',
		importmeta:'loadmeta.file',
		upload:'upload.file'
	},
	sample:{
		load:'load.sample',   //呼起加载音频
		add:'add.sample',   //音频被添加事件
		timing: 'timing.sample',
		edit:'edit.sample'
	},
	layer:{
		added:'add.layer',
		del:'delete.layer'
	},
	grid:{
		change: 'change.grid',
        interval_change: 'change.interval',
		layer: 'change.layer.grid',
		focus:'focus.grid',
		line:'line.grid',
		bpm: 'bpm.grid',
		sync: 'sync.grid',
		align:'align.grid',  //重对齐note
		assign: 'assign.grid',   // 给选中的note分配新属性
        interval: 'interval.grid' //pad模式最小纵连
	},
	timing:{
		change:'change.timing'
	},
	note:{
		load:'load.note',
		unload:'unload.note',
		change:'change.note',
        simplify:'simplify.note',
		touch:'touch.note'
	},
	app:{
		exit:"exit.app",
		showConsole:"showConsole.app"
	},
	key:{
		down:'down.key',
		up:'up.key',
		repeat:'repeat.key'
	},
	config:{
		lang: 'lang.config'
	},
	test:{
		start:'start.test',
		end:'end.test'
	},
	user:{
		login: 'login.user',
		logout: 'logout.user'
	},
	dialog:{
		welcome:'welcome.dialog',
		grid:'grid.dialog',
		gridaux:'aux.grid.dialog',
		about:'about.dialog',
		config:'config.dialog',
		bpm:'bpm.dialog',
		meta:'meta.dialog',
		newmeta:'meta.new.dialog',
		guide:'guide.dialog',
		create: 'create.dialog',
		user:'user.dialog',
        editmusic:'editmusic.dialog',
        readme: 'readme.dialog',
		movenote:'movenote.dialog',
		upload2: 'special.upload.dialog'
	},
	tutorial:{
		show : 'show.tutorial',
        end : 'end.tutorial'
	},
	urlopen : {
		website : 'website.urlopen',
		song: 'song.urlopen',
		chart:'chart.urlopen'
	}
};